package doip.performanceTest;

//import com.alibaba.fastjson.JSONObject;

import com.google.gson.Gson;
import org.apache.jmeter.samplers.AbstractSampler;
import org.apache.jmeter.samplers.Entry;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.testelement.TestStateListener;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.log.Logger;
import org.bdware.doip.codec.doipMessage.DoipMessage;
import org.bdware.doip.endpoint.client.DoipClientImpl;
import org.bdware.doip.endpoint.client.DoipMessageCallback;
import org.bdware.doip.endpoint.client.ClientConfig;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class DoipSampler extends AbstractSampler implements TestStateListener {
    private static final long serialVersionUID = 1L;
    private static final String DOA_AGREEMENT = "doip.agreement";
    private static final String DOA_IP = "doip.ip";
    private static final String DOA_PORT = "doip.port";
    private static final String DOA_METHOD = "doip.method";
    private static final String DOA_DOID = "doip.doid";
    //    private static final String DOA_PUBKEY = "doip.pubkey";
//    private static final String DOA_PRIKEY = "doip.prikey";
//    private static final String DOA_REPONAME = "doip.reponame";
//    private static final String DOA_REPOID = "doip.repoid";
//    private static final String DOA_INITIALVALUE = "0";
//    private static final String DOA_istrue = "true";
    private static final String DOA_BODY = "doip.body";
    private static final String RESULT = "error";

    private static final String HEALDER = "";

    Map<String, String> results = new HashMap<>();

    //    private static final String ELEMENT = null;
    //    private  static final boolean INCLUDE = true;
    //String aaaa = results.put("header","header");
    //String bbbb = results.put("body","body");
    private static final Logger log = LoggingManager.getLoggerForClass();

    public DoipSampler() {
        setName("Doip sampler");
    }


    @Override
    public SampleResult sample(Entry entry) {
        SampleResult result = new SampleResult();
        result.setSampleLabel(getName());
        try {
            result.sampleStart();
//            result.setRequestHeaders("服务器地址：" + getDoaAgreement() + "://" + getDoaIp() + ":" + getDoaPort() +
//                    '\n' + "请求公钥：" + getDoaPubkey() + '\n' + "请求私钥：" + getDoaPrikey() + '\n' + "请求方式：" +
//                    getDoaMethod() + '\n' + "DO类型：" + getDoaReponame() + '\n' + "仓库ID：" + getDoaRepoid() + '\n' + "请求参数：" + getDoaBody())
//            ;
            result.setRequestHeaders("服务器地址:" + getDoaAgreement() + "://" + getDoaIp() + ":" + getDoaPort() +
                    '\n' + "请求方式:" + getDoaMethod() + '\n' + "标识:" + getDoaDoid())
            ;

            RunDoip();
            result.setResponseHeaders(results.get("header"));
            result.setResponseData(results.get("body"), "UTF-8");
            result.sampleEnd();
            result.setSuccessful(true);
            result.setResponseCodeOK();
        } catch (Exception e) {
            result.sampleEnd(); // stop stopwatch
            result.setSuccessful(false);
            result.setResponseMessage("Exception: " + e);
            java.io.StringWriter stringWriter = new java.io.StringWriter();
            e.printStackTrace(new java.io.PrintWriter(stringWriter));
            result.setResponseData(stringWriter.toString(), null);
            result.setDataType(SampleResult.TEXT);
            result.setResponseCode("FAILED");
        }
        return result;
    }

    private void RunDoip() throws InterruptedException {

        final CountDownLatch countDownLatch = new CountDownLatch(1);
        try {
            String url = getDoaAgreement() + "://" + getDoaIp() + ":" + getDoaPort();
            String protocol = getDoaMethod();
            if (protocol.equals("retrieve")) {
                String repoURL = url;
                final DoipClientImpl doipClient = new DoipClientImpl();
                doipClient.connect(ClientConfig.fromUrl(repoURL));
                if(!doipClient.isConnected()){
                    throw new InterruptedException("error");
                }
                doipClient.retrieve(getDoaDoid(), null, true, new DoipMessageCallback() {
                    @Override
                    public void onResult(DoipMessage msg) {
                        //获取do信息
                        String body = msg.body.getDataAsJsonString();
                        String header = new Gson().toJson(msg.header.parameters);
                        //setresult(body);
                        //setHealder(header);
                        results.put("header", header);
                        results.put("body", body);
                        //关闭连接
                        if (doipClient != null) doipClient.close();
                        countDownLatch.countDown();
                    }
                });
            } else {
                log.info("$$$$$$$$$$$$$$$$$$$$#protocol is error#$$$$$$$$$$$$$$$$$$$$");
                results.put("body", "error:protocol is error");
            }
        } catch (Exception e) {
            log.info("$$$$$$$$$$$$$$$$$$$$#doip is error#$$$$$$$$$$$$$$$$$$$$" + '\n' + e);
            //setresult("error:" + e);
            results.put("body", "error:" + e);
        }
        countDownLatch.await(5000, TimeUnit.MILLISECONDS);
    }

//    public String getjsonstr(String param) {
//        JSONObject json = JSONObject.parseObject(getDoaBody());
//        //System.out.println(json.getString(param));
//        return json.getString(param);
//    }
//
//    public String getresult() {
//        return getPropertyAsString(RESULT);
//    }

//    public void setresult(String result) {
//        setProperty(RESULT, result);
//    }
//
//    public String getHealder() {
//        return getPropertyAsString(HEALDER);
//    }
//
//    public void setHealder(String healder) {
//        setProperty(HEALDER, healder);
//    }

    public String getDoaAgreement() {
        return getPropertyAsString(DOA_AGREEMENT);
    }

    public void setDoaAgreement(String doip_agreement) {
        setProperty(DOA_AGREEMENT, doip_agreement);
    }

    public String getDoaIp() {
        return getPropertyAsString(DOA_IP);
    }

    public void setDoaIp(String doip_ip) {
        setProperty(DOA_IP, doip_ip);
    }

    public String getDoaPort() {
        return getPropertyAsString(DOA_PORT);
    }

    public void setDoaPort(String doip_port) {
        setProperty(DOA_PORT, doip_port);
    }

//    public String getDoaPubkey() {
//        return getPropertyAsString(DOA_PUBKEY);
//    }

//    public void setDoaPubkey(String pubkey) {
//        setProperty(DOA_PUBKEY, pubkey);
//    }

//    public String getDoaPrikey() {
//        return getPropertyAsString(DOA_PRIKEY);
//    }

//    public void setDoaPrikey(String prikey) {
//        setProperty(DOA_PRIKEY, prikey);
//    }

//    public String getDoaistrue() {
//        return getPropertyAsString(DOA_istrue);
//    }

//    public void setDoaistrue(String istrue) {
//        setProperty(DOA_istrue, istrue);
//    }

    public String getDoaMethod() {
        return getPropertyAsString(DOA_METHOD);
    }

    public void setDoaMethod(String doip_method) {
        setProperty(DOA_METHOD, doip_method);
    }

    public String getDoaDoid() {
        return getPropertyAsString(DOA_DOID);
    }

    public void setDoaDoid(String doip_doid) {
        setProperty(DOA_DOID, doip_doid);
    }

//    public String getDoaReponame() {
//        return getPropertyAsString(DOA_REPONAME);
//    }
//
//    public void setDoaReponame(String doip_brssize) {
//        setProperty(DOA_REPONAME, doip_brssize);
//    }
//
//    public String getDoaRepoid() {
//        return getPropertyAsString(DOA_REPOID);
//    }
//
//    public void setDoaRepoid(String doip_brgsize) {
//        setProperty(DOA_REPOID, doip_brgsize);
//    }

    public String getDoaBody() {
        return getPropertyAsString(DOA_BODY);
    }

    public void setDoaBody(String body) {
        setProperty(DOA_BODY, body);
    }

//    public String getElement() {
//        return getPropertyAsString(ELEMENT);
//    }
//
//    public void setElement(String element) {
//        setProperty(ELEMENT, element);
//    }
//
//    public boolean getInclude() {
//        return getPropertyAsBoolean(String.valueOf(INCLUDE));
//    }
//
//    public void setInclude(boolean include) {setProperty(String.valueOf(INCLUDE), include); }
//    public String getDoaInitialvalue() {
//        return getPropertyAsString(DOA_INITIALVALUE);
//    }
//
//    public void setDoaInitialvalue(String doip_initialvalue) {
//        setProperty(DOA_INITIALVALUE, doip_initialvalue);
//    }


    @Override
    public void testEnded() {
        this.testEnded("local");
    }

    @Override
    public void testEnded(String arg0) {
//		Iterator<Producer<String, String>> it = producers.values().iterator();
//		while(it.hasNext()) {
//			Producer<String, String> producer = it.next();
//			producer.close();
//		}
    }

    @Override
    public void testStarted() {
    }

    @Override
    public void testStarted(String arg0) {
    }


}
